/*
   Most coded is unchanged but some functions are modified or added
   for MultiTrigger functionality 
    
*/

/* ----------------------------------------------------------------------------
	   
    128x64 Graphic LCD management for SSD1306 driver

	FILE NAME 	: SSD1306.c
	LAYER		: Application
	
	DESCRIPTION	: The purpose of this function is to manage a graphic LCD
			  by providing function for control and display text and 
			  graphic 
			  
	AUTHOR		: Gabriel Anzziani
    www.gabotronics.com

 */
 
/******************************************************************************
/                       DECLARATIONS / DEFINITIONS                            /
/ ****************************************************************************/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include "display.h"
#include "mygccdef.h"

/* Local functions prototypes */
void LcdDataWrite (unsigned char);
void LcdWaitBusy (void);


uint8_t display_standbystate=0;
/******************************************************************************
/                               PROGRAM CODE                                  /
/ ****************************************************************************/


void GLCD_LcdPortInit(void){
    
        PORTD.DIR |= (1<<PIN1) | (1<<PIN3) | (1<<PIN4);
        PORTD.OUTCLR = (1<<PIN1) | (1<<PIN3)| (1<<PIN4);
        
        // Initialize USARTD0 for OLED in SPI mode
        USARTD0.BAUDCTRLA = 0x01;   // BSEL=1 (SPI clock = 1MHz)
        USARTD0.CTRLC     = USART_CMODE_MSPI_gc;   // Master SPI mode,
        USARTD0.CTRLB     = USART_TXEN_bm;   // Enable TX

        //Set Virtual Port to PortB for faster OLED access
        PORTCFG.VPCTRLA = 0x01;
}
/*-----------------------------------------------------------------------------
LCD Initialization
	GLCD_LcdINIT()
-----------------------------------------------------------------------------*/
void GLCD_LcdInit(void)	{
    // Recommended power up sequence
    clrbit(LCD_CTRL, LCD_RESET);         // Reset Low for 3 uS
  	_delay_us(3);
    setbit(LCD_CTRL, LCD_RESET);         // Reset Low for 3 uS
    _delay_us(3);
    // Recommended initialization sequence
    LcdInstructionWrite(LCD_DISP_OFF);
    LcdInstructionWrite(LCD_SET_RATIO_OSC);
    LcdInstructionWrite(0x80);
    LcdInstructionWrite(LCD_MULTIPLEX);
    LcdInstructionWrite(0x3F);
    LcdInstructionWrite(LCD_SET_OFFSET);
    LcdInstructionWrite(0x00);
    LcdInstructionWrite(LCD_SET_LINE);
    LcdInstructionWrite(LCD_CHARGE_PUMP);
    LcdInstructionWrite(LCD_PUMP_ON);
//set at main LcdInstructionWrite(LCD_SET_SEG_REMAP1);
//set at main LcdInstructionWrite(LCD_SET_SCAN_NOR);
    LcdInstructionWrite(LCD_SET_PADS);
    LcdInstructionWrite(0x12);
    LcdInstructionWrite(LCD_SET_CONTRAST);
    LcdInstructionWrite(0x8F);
    LcdInstructionWrite(LCD_SET_CHARGE);
    LcdInstructionWrite(0xF1);
    LcdInstructionWrite(LCD_SET_VCOM);
    LcdInstructionWrite(0x40);
    LcdInstructionWrite(LCD_EON_OFF);
    LcdInstructionWrite(LCD_DISP_NOR);
    LcdInstructionWrite(LCD_MEM_ADDRESSING);
    LcdInstructionWrite(0x00);          // Horizontal Addressing mode
    LcdInstructionWrite(LCD_DISP_ON);
	
}

void GLCD_LcdOff(void)	{
   LcdInstructionWrite(LCD_DISP_OFF);

   // LcdInstructionWrite(LCD_EON_OFF);
 //   LcdInstructionWrite(LCD_CHARGE_PUMP);
  //  LcdInstructionWrite(LCD_PUMP_OFF);
}

void GLCD_LcdOn(void)	{
   
  
    //LcdInstructionWrite(LCD_CHARGE_PUMP);
  //  LcdInstructionWrite(LCD_PUMP_ON);
	 LcdInstructionWrite(LCD_DISP_ON);

}

/*-------------------------------------------------------------------------------
Send instruction to the LCD
	LcdInstructionWrite (uint8_t u8Instruction)
		u8Instruction = Instruction to send to the LCDCHSIZE 2 2469
-------------------------------------------------------------------------------*/
void LcdInstructionWrite (uint8_t u8Instruction) {
    
	clrbit(LCD_CTRL, LCD_CS);			// Select
    cli();
    clrbit(LCD_CTRL,LCD_RS);        // Instruction mode
    USARTD0.DATA= u8Instruction;
    while(!testbit(USARTD0.STATUS,6));     // Wait until transmit done
    setbit(USARTD0.STATUS,6);
	sei();
}

// Transfer display buffer to LCD
void show_display(void) {
    uint16_t i;
    uint8_t *p=display_buffer;
    if(display_standbystate == 1)
        return;
    clrbit(LCD_CTRL, LCD_CS);               // Select

    LcdInstructionWrite(LCD_SET_PAGE);
    LcdInstructionWrite(LCD_SET_COL_HI);    // Set column at 0
    LcdInstructionWrite(LCD_SET_COL_LO);
 cli();
    setbit(LCD_CTRL, LCD_RS);               // Data mode
   	// Send data to display
    for(i=0; i<1024; i++) {
        while(!testbit(USARTD0.STATUS,5));  // Wait for DATA empty
	    USARTD0.DATA= *p++;
    }
	
    while(!testbit(USARTD0.STATUS,6));      // Wait until transmit done
	 
    setbit(USARTD0.STATUS,6);               // Clear flag
    setbit(LCD_CTRL, LCD_CS);               // No Select
	sei();
}

